﻿using System.Collections.Generic;
using System.Data;
using System.Linq;
using Monkey.Warrenty.Bo;
using Monkey.Warrenty.Data.Interfaces;
using Monkey.Warrenty.EntityModel;
using Monkey.Warrenty.Enum;

namespace Monkey.Warrenty.Data
{
    public class WarrantyTicketDao : IWarrantyTicketDao
    {
        public List<WarrantyTicketView> GetTicketViews(int startIndex, int count, string sorting, int status)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                IEnumerable<WarrantyTicketView> query = context.WarrantyTicketViews;

                //Filters
                if (status > 0)
                {
                    query = query.Where(x => x.StatusId == status);
                }

                // sorting
                if (string.IsNullOrEmpty(sorting) || sorting.Equals("DeliveryDate ASC"))
                {
                    query = query.OrderBy(x => x.DeliveryDate);
                }
                else if (sorting.Equals("DeliveryDate DESC"))
                {
                    query = query.OrderByDescending(x => x.DeliveryDate);
                }
                if (string.IsNullOrEmpty(sorting) || sorting.Equals("CreatedDate ASC"))
                {
                    query = query.OrderBy(x => x.CreatedDate);
                }
                else if (sorting.Equals("CreatedDate DESC"))
                {
                    query = query.OrderByDescending(x => x.CreatedDate);
                }
                else if (sorting.Equals("Code ASC"))
                {
                    query = query.OrderBy(x => x.Code);
                }
                else if (sorting.Equals("Code DESC"))
                {
                    query = query.OrderByDescending(x => x.Code);
                }
                else if (sorting.Equals("CreatedEmployeeName ASC"))
                {
                    query = query.OrderBy(x => x.CreatedEmployeeName);
                }
                else if (sorting.Equals("CreatedEmployeeName DESC"))
                {
                    query = query.OrderByDescending(x => x.CreatedEmployeeName);
                }
                else if (sorting.Equals("CustomerName ASC"))
                {
                    query = query.OrderBy(x => x.CustomerName);
                }
                else if (sorting.Equals("CustomerName DESC"))
                {
                    query = query.OrderByDescending(x => x.CustomerName);
                }

                return count > 0
                           ? query.Skip(startIndex).Take(count).ToList() //Paging
                           : query.ToList(); //No paging
            }
        }

        public List<WarrantyTicketView> GetActiveTicketViews(int startIndex, int count, string sorting)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                IEnumerable<WarrantyTicketView> query = context.WarrantyTicketViews;

                //Filters
                query = query.Where(x => x.StatusId == (int)WarrantyTicketStatus.Received
                    || x.StatusId == (int)WarrantyTicketStatus.Processing);

                // sorting
                if (string.IsNullOrEmpty(sorting) || sorting.Equals("DeliveryDate ASC"))
                {
                    query = query.OrderBy(x => x.DeliveryDate);
                }
                else if (sorting.Equals("DeliveryDate DESC"))
                {
                    query = query.OrderByDescending(x => x.DeliveryDate);
                }
                if (string.IsNullOrEmpty(sorting) || sorting.Equals("CreatedDate ASC"))
                {
                    query = query.OrderBy(x => x.CreatedDate);
                }
                else if (sorting.Equals("CreatedDate DESC"))
                {
                    query = query.OrderByDescending(x => x.CreatedDate);
                }
                else if (sorting.Equals("Code ASC"))
                {
                    query = query.OrderBy(x => x.Code);
                }
                else if (sorting.Equals("Code DESC"))
                {
                    query = query.OrderByDescending(x => x.Code);
                }
                else if (sorting.Equals("CreatedEmployeeName ASC"))
                {
                    query = query.OrderBy(x => x.CreatedEmployeeName);
                }
                else if (sorting.Equals("CreatedEmployeeName DESC"))
                {
                    query = query.OrderByDescending(x => x.CreatedEmployeeName);
                }
                else if (sorting.Equals("CustomerName ASC"))
                {
                    query = query.OrderBy(x => x.CustomerName);
                }
                else if (sorting.Equals("CustomerName DESC"))
                {
                    query = query.OrderByDescending(x => x.CustomerName);
                }

                return count > 0
                           ? query.Skip(startIndex).Take(count).ToList() //Paging
                           : query.ToList(); //No paging
            }
        }

        public int GetTicketCountByFilter(int statusId)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                IEnumerable<WarrantyTicketView> query = context.WarrantyTicketViews;

                //Filters
                if (statusId > 0)
                {
                    query = query.Where(x => x.StatusId == statusId);
                }

                return query.Count();
            }
        }

        public int GetActiveTicketCount()
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                IEnumerable<WarrantyTicketView> query = context.WarrantyTicketViews;
                
                query = query.Where(x => x.StatusId == (int)WarrantyTicketStatus.Received
                    || x.StatusId == (int)WarrantyTicketStatus.Processing);

                return query.Count();
            }
        }

        public long GetCurrentIdentity()
        {
            long? identity;
            using (var context = new MonkeyWarrantyEntities())
            {
                identity = context.GetIdentity("WarrantyTickets").SingleOrDefault();
            }

            return identity.HasValue ? identity.Value : 0;
        }

        public WarrantyTicket AddTicket(WarrantyTicket ticket)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                context.WarrantyTickets.AddObject(ticket);
                context.SaveChanges();
            }

            return ticket;
        }

        public WarrantyTicket GetById(long id)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                return context.WarrantyTickets.FirstOrDefault(x => x.Id == id);
            }
        }

        public void UpdateTicket(WarrantyTicket ticket)
        {
            if (ticket == null || ticket.Id == 0) return;

            using (var context = new MonkeyWarrantyEntities())
            {
                context.WarrantyTickets.Attach(ticket);
                context.ObjectStateManager.ChangeObjectState(ticket, EntityState.Modified);
                context.SaveChanges();
            }
        }

        public void DeleteTicket(long id)
        {
            using (var db = new MonkeyWarrantyEntities())
            {
                var ticket = new WarrantyTicket() { Id = id };
                db.WarrantyTickets.Attach(ticket);
                db.DeleteObject(ticket);
                db.SaveChanges();
            }
        }

        #region Products

        public List<WarrantyTicketProductView> GetTicketProducts(long ticketId)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                return context.WarrantyTicketProductViews.Where(x => x.WarrantyTicketId == ticketId).ToList();
            }
        }

        public void DeleteTicketProduct(long ticketProductId)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                var ticketProduct = context.WarrantyTickets_Products.FirstOrDefault(x => x.Id == ticketProductId);
                if (ticketProduct == null) return;
                context.DeleteObject(ticketProduct);
                context.SaveChanges();
            }
        }

        public WarrantyTicket_Product CreateTicketProduct(WarrantyTicket_Product ticketProduct)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                context.WarrantyTickets_Products.AddObject(ticketProduct);
                context.SaveChanges();
            }

            return ticketProduct;
        }

        public WarrantyTicket_Product GetTicketProductById(long id)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                return context.WarrantyTickets_Products.FirstOrDefault(x => x.Id == id);
            }
        }

        public void UpdateTicketProduct(WarrantyTicket_Product ticketProduct)
        {
            if (ticketProduct == null || ticketProduct.Id == 0) return;

            using (var context = new MonkeyWarrantyEntities())
            {
                context.WarrantyTickets_Products.Attach(ticketProduct);
                context.ObjectStateManager.ChangeObjectState(ticketProduct, EntityState.Modified);
                context.SaveChanges();
            }
        }

        #endregion

        #region Lend Products

        public List<WarrantyTicketLendProductView> GetTicketLendProducts(long ticketId)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                return context.WarrantyTicketLendProductViews.Where(x => x.WarrantyTicketId == ticketId).ToList();
            }
        }

        public void DeleteTicketLendProduct(long ticketProductId)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                var ticketProduct = context.WarrantyTickets_LendProducts.FirstOrDefault(x => x.Id == ticketProductId);
                if (ticketProduct == null) return;
                context.DeleteObject(ticketProduct);
                context.SaveChanges();
            }
        }

        public WarrantyTicket_LendProduct CreateTicketLendProduct(WarrantyTicket_LendProduct ticketProduct)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                context.WarrantyTickets_LendProducts.AddObject(ticketProduct);
                context.SaveChanges();
            }

            return ticketProduct;
        }

        public WarrantyTicket_LendProduct GetTicketLendProductById(long id)
        {
            using (var context = new MonkeyWarrantyEntities())
            {
                return context.WarrantyTickets_LendProducts.FirstOrDefault(x => x.Id == id);
            }
        }

        public void UpdateTicketLendProduct(WarrantyTicket_LendProduct ticketProduct)
        {
            if (ticketProduct == null || ticketProduct.Id == 0) return;

            using (var context = new MonkeyWarrantyEntities())
            {
                context.WarrantyTickets_LendProducts.Attach(ticketProduct);
                context.ObjectStateManager.ChangeObjectState(ticketProduct, EntityState.Modified);
                context.SaveChanges();
            }
        }

        public void UpdateTicketStatus(long ticketId, int status)
        {
            if (ticketId <= 0 || status <= 0) return;
            using (var db = new MonkeyWarrantyEntities())
            {
                var ticket = db.WarrantyTickets.SingleOrDefault(x => x.Id == ticketId);
                if (ticket == null || ticket.StatusId == status) return;
                ticket.StatusId = status;
                db.SaveChanges();
            }
        }

        #endregion

        #region Printing Methods

        public WarrantyTicketPrintBo GetWarrantyTicketForPrint(long id)
        {
            WarrantyTicketPrintBo warrantyTicketPrintBo = null;

            using (var context = new MonkeyWarrantyEntities())
            {
                var query = from ticket in context.WarrantyTickets
                            join customer in context.Customers on ticket.CustomerId equals customer.Id
                            join employee in context.Employees on ticket.CreatedEmployeeId equals employee.Id
                            where ticket.Id == id
                            select new { Ticket = ticket, CreatedEmployee = employee, Customer = customer };
                var item = query.FirstOrDefault();

                if (item != null)
                {
                    warrantyTicketPrintBo = new WarrantyTicketPrintBo
                    {
                        WarrantyTicketId = id,
                        WarrantyTicketCode = item.Ticket.Code,
                        WarrantyTicketContent = item.Ticket.TicketContent,
                        WarrantyTicketDate = item.Ticket.CreatedDate,
                        CustomerName = item.Customer.Name,
                        CustomerAddress = item.Customer.Address,
                        CustomerPhone = item.Customer.Phone,
                        Employee1 = item.CreatedEmployee.Name
                    };
                }
            }

            return warrantyTicketPrintBo;
        }

        public List<TaskServiceBo> GetWarrantyTicketProductsForPrint(long id)
        {
            var ticketDetails = new List<TaskServiceBo>();

            using (var context = new MonkeyWarrantyEntities())
            {
                var index = 0;
                // get products
                var query = from tp in context.WarrantyTickets_Products
                            join p in context.Products on tp.ProductId equals p.Id into list1
                            join e in context.Errors on tp.ErrorId equals e.Id into list2
                            join wt in context.WarrantyTypes on tp.WarrantyTypeId equals wt.Id into list3
                            where tp.WarrantyTicketId == id

                            from l1 in list1.DefaultIfEmpty()
                            from l2 in list2.DefaultIfEmpty()
                            from l3 in list3.DefaultIfEmpty()
                            select new
                            {
                                tp.Quantity,
                                tp.WarrantyDate,
                                ProductName = l1.Name,
                                ErrorName = l2.Name,
                                TypeName = l3.Name
                            };

                var ticketProductDetails = query.ToList();

                foreach (var ticketProductDetail in ticketProductDetails)
                {
                    index++;
                    ticketDetails.Add(new TaskServiceBo
                    {
                        OrderNumber = index,
                        Name = ticketProductDetail.ProductName,
                        Quantity = ticketProductDetail.Quantity,
                        WarrantyDate = ticketProductDetail.WarrantyDate,
                        ErrorName = ticketProductDetail.ErrorName,
                        TypeName = ticketProductDetail.TypeName
                    });
                }
            }

            return ticketDetails;
        }

        public List<TaskServiceBo> GetWarrantyTicketLendProductsForPrint(long id)
        {
            var ticketDetails = new List<TaskServiceBo>();

            using (var context = new MonkeyWarrantyEntities())
            {
                var index = 0;
                // get products
                var query = from tp in context.WarrantyTickets_LendProducts
                            join p in context.Products on tp.ProductId equals p.Id into list1
                            //join e in context.Errors on tp.ErrorId equals e.Id into list2
                            //join wt in context.WarrantyTypes on tp.WarrantyTypeId equals wt.Id into list3
                            where tp.WarrantyTicketId == id

                            from l1 in list1.DefaultIfEmpty()
                            //from l2 in list2.DefaultIfEmpty()
                            //from l3 in list3.DefaultIfEmpty()
                            select new
                            {
                                tp.Quantity,
                                //tp.WarrantyDate,
                                ProductName = l1.Name,
                                //ErrorName = l2.Name,
                                //TypeName = l3.Name
                            };

                var ticketProductDetails = query.ToList();

                foreach (var ticketProductDetail in ticketProductDetails)
                {
                    index++;
                    ticketDetails.Add(new TaskServiceBo
                    {
                        OrderNumber = index,
                        Name = ticketProductDetail.ProductName,
                        Quantity = ticketProductDetail.Quantity,
                        //WarrantyDate = ticketProductDetail.WarrantyDate,
                        //ErrorName = ticketProductDetail.ErrorName,
                        //TypeName = ticketProductDetail.TypeName
                    });
                }
            }

            return ticketDetails;
        }

        #endregion
    }
}
